

#ifndef __CS_H__
#define __CS_H__

#include <crystalspace.h>
#include "console.h"

//CS includes
#include <cstool/initapp.h>
#include <csutil/sysfunc.h>
#include <csutil/event.h>
#include <iutil/eventq.h>
#include <iutil/event.h>
#include <iutil/csinput.h>
#include <iutil/vfs.h>
#include <iutil/object.h>
#include <iutil/objreg.h>
#include <iutil/plugin.h>
#include <ivaria/collider.h>
#include <imap/modelload.h>
// Sound
#include <isndsys/ss_source.h>
#include <isndsys/ss_loader.h>
#include <isndsys/ss_renderer.h>
#include <isndsys/ss_manager.h>
//CEL includes:
//#include "physicallayer/pl.h"
//#include "behaviourlayer/bl.h"
//#include "physicallayer/propclas.h"


#include "framelimiter.h"
#include "intro.h"
#include "menu.h"
#include "game.h"


struct iJoystickDriver;

enum game_state {eInit, eIntro, eMenuInit, eMenu, eGameInit, eGame, eExit};

class catchthealien : public csApplicationFramework, public csBaseEventHandler
{
private:
	game_state cta_state_;
    cta::framelimiter framelimiter_;
    cta::intro intro_;
    cta::menu menu_;
    cta::game game_;

    std::string game_type;
public:
	void setGameType(char* type);
    bool InitCTA();
	bool RunCTA();
	game_state getCta_state() const
    {
        return cta_state_;
    }

public:
	csRef<ctaConsole> console;
/// A pointer to the configuration manager.
    csRef<iConfigManager> confman;

	csRef<iDataBuffer> data;

/// A pointer to the cel billboard
//	csRef<iCelPlLayer> pl;
//	csRef<iCelBlLayer> bltest;

  bool Setup ();





  /// A pointer to the plugin manager plugin
  csRef<iPluginManager> plugin_mgr;

  /// A pointer to the model loader plugin
  csRef<iModelLoader> model_ldr;



  /// A pointer to the keyboard driver.
  csRef<iKeyboardDriver> kbd;

  /// A pointer to the joystick driver.
  csRef<iJoystickDriver> joy;



  /// A pointer to the collision detection system.
  csRef<iCollideSystem> cdsys;

  csRef<iReporter> reporter;

  /// A Pointer to the reporter listener
  csRef<iStandardReporterListener> listener;



  /// A pointer to the sector the camera will be in.
  iSector* room;


  /// Our collider used for gravity and CD.
  csColliderActor collider_actor;

  // THE GAME


  /**
   * Handle keyboard events - ie key presses and releases.
   * This routine is called from the event handler in response to a
   * csevKeyboard event.
   */
  bool OnKeyboard (iEvent&);

  /**
   * Setup everything that needs to be rendered on screen. This routine
   * is called from the event handler in response to a csevProcess
   * broadcast message.
   */
  void ProcessFrame ();

  /**
   * Finally render the screen. This routine is called from the event
   * handler in response to a csevFinalProcess broadcast message.
   */
  void FinishFrame ();

  bool LoadConfig();

  bool use_console;
  csString startmap;
  csString debug_filename;
  bool enable_logging;
  bool append_logfile;

public:

  /// Construct our game. This will just set the application ID for now.
  catchthealien ();

  /// Destructor.
  ~catchthealien ();

  /// Final cleanup.
  void OnExit ();

  /**
   * Main initialization routine. This routine will set up some basic stuff
   * (like load all needed plugins, setup the event handler, ...).
   * In case of failure this routine will return false. You can assume
   * that the error message has been reported to the user.
   */
  bool OnInitialize (int argc, char* argv[]);

  /**
   * Run the application.
   * First, there are some more initialization (everything that is needed
   * by cimGame to use Crystal Space), then this routine fires up the main
   * event loop. This is where everything starts. This loop will  basically
   * start firing events which actually causes Crystal Space to function.
   * Only when the program exits this function will return.
   */
  bool Application ();

  CS_EVENTHANDLER_NAMES ("application.cta");
  CS_EVENTHANDLER_NIL_CONSTRAINTS

  // TODO: Solve singleton
  static catchthealien& c(){
	  static catchthealien singleton;
	  return singleton;
  }
};

#endif
